# include <string>
# include <vector> 
# define MSG_SIZE 500
# define NAME_LEN 30
# define MAX_MSGSIZE 10240
# define TRIES 5
# define MSG_DATAMSG 0
# define MSG_CLIENTCHECKSALIVE 1
# define MSG_SERVERCHECKSALIVE 2
# define MSG_RETRANSMITDATA 3
# define MSG_ADDIPTOTABLE 4
# define MSG_REMOVEFROMIPTABLE 5
# define MSG_CHECKNEXTSERVERALIVE 6
# define MSG_CHECKNEXTSERVERALIVEREPLY 7
# define MSG_UPDATECURRENTSEQUENCER 8
# define MSG_SAFETOKILLSELFNOW 9
# define MSG_REBOOT 10
# define MSG_ASKCLIENTRETRANSMIT 11
# define MSG_NOWSAFETOKILLSELFNOW 12

using namespace std;
class Message  {
 public:
  //pthread_mutex mutualEx;
  int seqno;
  string username;
  string message;
  int messagetype;
  int instancenumber;
  friend ostream& operator<< (ostream& out, Message& object) {
    out << object.seqno << "|" <<object.username <<"|" << object.message<<"|"<<object.instancenumber <<"|"<<object.messagetype ;
    return out;
  }
};

typedef struct thr_data
{
  int callType;
  int portNum;
} listeningThData;

class DistChat
{
 public:
 static bool endofObject;
  static bool isNxtSequencer;
  static int sock;
  static int currentSequenceNum; 
  static char userName[NAME_LEN];
  static int chatport;
  static string hostIP;
  static string currentClientIP;
  static int seqno; 
  static int currentClientSequenceNumber;
  static vector <string> iptables;
  static vector <Message> messageQueue;
  static vector <string> currIPtable;
  static vector <Message> sentMessages;

  // map<long, string> ipMap;
  static bool firstMessage;
  //static int userNo;
  DistChat();
  ~DistChat();  
  DistChat(vector<string> ipt){
    this->iptables = ipt;
  };
  
  static char* getIPAddress();
  static void listen(int portNum); 
  static void broadcast(Message message);
  static void send(char * argv[], const char* send_data);
  
};
